package com.geo.ai.exception;

import lombok.Getter;

/**
 * AI模型调用异常类
 * 用于处理AI模型调用过程中的各种异常情况
 * 
 * @author GEO Team
 * @version 1.0.0
 */
@Getter
public class AIException extends Exception {
    
    /**
     * 错误代码
     */
    private final String errorCode;
    
    /**
     * 错误类型
     */
    private final ErrorType errorType;
    
    /**
     * 模型提供商
     */
    private final String provider;
    
    /**
     * 请求ID
     */
    private final String requestId;
    
    /**
     * 错误类型枚举
     */
    public enum ErrorType {
        AUTHENTICATION_ERROR("认证错误"),
        AUTHORIZATION_ERROR("授权错误"),
        RATE_LIMIT_ERROR("限流错误"),
        QUOTA_EXCEEDED_ERROR("配额超限错误"),
        NETWORK_ERROR("网络错误"),
        TIMEOUT_ERROR("超时错误"),
        MODEL_ERROR("模型错误"),
        INVALID_REQUEST_ERROR("无效请求错误"),
        SERVICE_UNAVAILABLE_ERROR("服务不可用错误"),
        UNKNOWN_ERROR("未知错误");
        
        private final String description;
        
        ErrorType(String description) {
            this.description = description;
        }
        
        public String getDescription() {
            return description;
        }
    }
    
    /**
     * 构造函数
     */
    public AIException(String message) {
        super(message);
        this.errorCode = "UNKNOWN";
        this.errorType = ErrorType.UNKNOWN_ERROR;
        this.provider = null;
        this.requestId = null;
    }
    
    /**
     * 构造函数
     */
    public AIException(String message, Throwable cause) {
        super(message, cause);
        this.errorCode = "UNKNOWN";
        this.errorType = ErrorType.UNKNOWN_ERROR;
        this.provider = null;
        this.requestId = null;
    }
    
    /**
     * 构造函数
     */
    public AIException(String errorCode, String message, ErrorType errorType) {
        super(message);
        this.errorCode = errorCode;
        this.errorType = errorType;
        this.provider = null;
        this.requestId = null;
    }
    
    /**
     * 构造函数
     */
    public AIException(String errorCode, String message, ErrorType errorType, String provider) {
        super(message);
        this.errorCode = errorCode;
        this.errorType = errorType;
        this.provider = provider;
        this.requestId = null;
    }
    
    /**
     * 构造函数
     */
    public AIException(String errorCode, String message, ErrorType errorType, String provider, String requestId) {
        super(message);
        this.errorCode = errorCode;
        this.errorType = errorType;
        this.provider = provider;
        this.requestId = requestId;
    }
    
    /**
     * 构造函数
     */
    public AIException(String errorCode, String message, ErrorType errorType, String provider, String requestId, Throwable cause) {
        super(message, cause);
        this.errorCode = errorCode;
        this.errorType = errorType;
        this.provider = provider;
        this.requestId = requestId;
    }
    
    /**
     * 检查是否为可重试的错误
     */
    public boolean isRetryable() {
        switch (errorType) {
            case NETWORK_ERROR:
            case TIMEOUT_ERROR:
            case SERVICE_UNAVAILABLE_ERROR:
            case RATE_LIMIT_ERROR:
                return true;
            case AUTHENTICATION_ERROR:
            case AUTHORIZATION_ERROR:
            case QUOTA_EXCEEDED_ERROR:
            case INVALID_REQUEST_ERROR:
            case MODEL_ERROR:
                return false;
            default:
                return false;
        }
    }
    
    /**
     * 检查是否为暂时性错误
     */
    public boolean isTemporary() {
        switch (errorType) {
            case RATE_LIMIT_ERROR:
            case NETWORK_ERROR:
            case TIMEOUT_ERROR:
            case SERVICE_UNAVAILABLE_ERROR:
                return true;
            default:
                return false;
        }
    }
    
    /**
     * 获取建议的重试延迟时间(毫秒)
     */
    public long getSuggestedRetryDelay() {
        switch (errorType) {
            case RATE_LIMIT_ERROR:
                return 60000; // 1分钟
            case NETWORK_ERROR:
                return 5000;  // 5秒
            case TIMEOUT_ERROR:
                return 10000; // 10秒
            case SERVICE_UNAVAILABLE_ERROR:
                return 30000; // 30秒
            default:
                return 0;
        }
    }
    
    /**
     * 获取详细的错误描述
     */
    public String getDetailedMessage() {
        StringBuilder sb = new StringBuilder();
        sb.append("AI调用异常: ");
        
        if (provider != null) {
            sb.append("[").append(provider).append("] ");
        }
        
        sb.append(errorType.getDescription());
        sb.append(" - ").append(getMessage());
        
        if (errorCode != null && !errorCode.equals("UNKNOWN")) {
            sb.append(" (错误代码: ").append(errorCode).append(")");
        }
        
        if (requestId != null) {
            sb.append(" (请求ID: ").append(requestId).append(")");
        }
        
        return sb.toString();
    }
    
    /**
     * 创建认证错误异常
     */
    public static AIException authenticationError(String provider, String message) {
        return new AIException("AUTH_FAILED", message, ErrorType.AUTHENTICATION_ERROR, provider);
    }
    
    /**
     * 创建授权错误异常
     */
    public static AIException authorizationError(String provider, String message) {
        return new AIException("UNAUTHORIZED", message, ErrorType.AUTHORIZATION_ERROR, provider);
    }
    
    /**
     * 创建限流错误异常
     */
    public static AIException rateLimitError(String provider, String message) {
        return new AIException("RATE_LIMITED", message, ErrorType.RATE_LIMIT_ERROR, provider);
    }
    
    /**
     * 创建配额超限错误异常
     */
    public static AIException quotaExceededError(String provider, String message) {
        return new AIException("QUOTA_EXCEEDED", message, ErrorType.QUOTA_EXCEEDED_ERROR, provider);
    }
    
    /**
     * 创建网络错误异常
     */
    public static AIException networkError(String provider, String message, Throwable cause) {
        return new AIException("NETWORK_ERROR", message, ErrorType.NETWORK_ERROR, provider, null, cause);
    }
    
    /**
     * 创建超时错误异常
     */
    public static AIException timeoutError(String provider, String message) {
        return new AIException("TIMEOUT", message, ErrorType.TIMEOUT_ERROR, provider);
    }
    
    /**
     * 创建模型错误异常
     */
    public static AIException modelError(String provider, String message) {
        return new AIException("MODEL_ERROR", message, ErrorType.MODEL_ERROR, provider);
    }
    
    /**
     * 创建无效请求错误异常
     */
    public static AIException invalidRequestError(String provider, String message) {
        return new AIException("INVALID_REQUEST", message, ErrorType.INVALID_REQUEST_ERROR, provider);
    }
    
    /**
     * 创建服务不可用错误异常
     */
    public static AIException serviceUnavailableError(String provider, String message) {
        return new AIException("SERVICE_UNAVAILABLE", message, ErrorType.SERVICE_UNAVAILABLE_ERROR, provider);
    }
    
    /**
     * 从HTTP状态码创建异常
     */
    public static AIException fromHttpStatus(String provider, int statusCode, String message) {
        switch (statusCode) {
            case 401:
                return authenticationError(provider, message);
            case 403:
                return authorizationError(provider, message);
            case 429:
                return rateLimitError(provider, message);
            case 402: // Payment Required
                return quotaExceededError(provider, message);
            case 400:
                return invalidRequestError(provider, message);
            case 500:
            case 502:
            case 503:
            case 504:
                return serviceUnavailableError(provider, message);
            default:
                return new AIException("HTTP_" + statusCode, message, ErrorType.UNKNOWN_ERROR, provider);
        }
    }
    
    @Override
    public String toString() {
        return String.format("AIException{errorCode='%s', errorType=%s, provider='%s', requestId='%s', message='%s'}", 
                errorCode, errorType, provider, requestId, getMessage());
    }
}